﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJ.Data;

namespace PJ.Business
{
    /// <summary>
    /// EntityService class
    /// </summary>
    /// <typeparam name="O">Object to serve type</typeparam>
    /// <typeparam name="OD">Inner data object type</typeparam>
    /// <typeparam name="ODP">Inner data object provider type</typeparam>
    public abstract class EntityService<TIEntity, OD, ODP> : DataObjectService<TIEntity, OD, ODP>, IEntityService<TIEntity>
        where TIEntity : class, IEntity
        where OD : class, IEntityData
        where ODP : class, IEntityProvider<OD>
    {
        #region Constructors
        protected EntityService(ODP dataService)
            : base(dataService)
        {
        }
        #endregion

        #region Public

        /// <summary>
        /// Gets the entity
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the entity with the given id does not exist.</exception>
        IEntity IEntityService.GetById(string id)
        {
            return GetById(id);
        }

        /// <summary>
        /// Gets the entity from cache first. If not found in cache, gets the entity from provider.
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the entity with the given id does not exist.</exception>
        IEntity IEntityService.CachedGetById(string id)
        {
            return CachedGetById(id);
        }

        /// <summary>
        /// Finds the entity
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        IEntity IEntityService.FindById(string id)
        {
            return FindById(id);
        }

        /// <summary>
        /// Finds the entity from cache first. If not found in cache, finds the entity from provider.
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        IEntity IEntityService.CachedFindById(string id)
        {
            return CachedFindById(id);
        }
        
        /// <summary>
        /// Gets the entity
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the entity with the given id does not exist.</exception>
        public TIEntity GetById(string id)
        {
            return CreateNewItem(DataService.GetById(id));
        }

        /// <summary>
        /// Gets the entity from cache first. If not found in cache, gets the entity from provider.
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        /// <exception cref="DataNotFoundException">If the entity with the given id does not exist.</exception>
        public TIEntity CachedGetById(string id)
        {
            return CreateNewItem(DataService.CachedGetById(id));
        }

        /// <summary>
        /// Finds the entity
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        public TIEntity FindById(string id)
        {
            return CreateNewItem(DataService.FindById(id));
        }

        /// <summary>
        /// Finds the entity from cache first. If not found in cache, finds the entity from provider.
        /// </summary>
        /// <param name="id">Entity id</param>
        /// <returns>The entity instance if found else null.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="id"/> is <see langref="null"/> or empty.</exception>
        public TIEntity CachedFindById(string id)
        {
            return CreateNewItem(DataService.CachedFindById(id));
        }

        #endregion

    }
}
